package com.kkk.shop.head.interceptor;

import java.net.URLEncoder;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kkk.shop.common.util.ConstantFinalUtil;
import com.kkk.shop.common.util.HttpUtil;
import com.kkk.shop.user.pojo.AUsers;
import com.kkk.shop.user.pojo.AUsersCar;
import com.kkk.shop.user.service.IUserService;

/**
 * 前台用户登陆拦截器
 * @author kkk
 */
@Component("loginAuthInterceptor")
public class LoginAuthInterceptor extends HandlerInterceptorAdapter
{
	@Resource
	private IUserService userService;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
	{
		ConstantFinalUtil.loggerMsg.info("---- 商城登陆验证----");
		HttpSession session = request.getSession() ; 
		
		/* 从session中获取admins对象(从用户中心获取的管理员JSON对象) */
		AUsers users = (AUsers) session.getAttribute("users");
		if(users != null)
		{
			/* 已经登陆 --- 放行*/
			return true ; 
		}
		
		/*---------------步骤3-------------*/
		/* 第一次登陆跳转和登陆成功后跳转,唯一不一样的是token,客户端是否需要跳转到用户中心登陆页面的标志就是:token */
		String token = request.getParameter("token") ; 
		/* 取最后一个token */
		/*String[] tokens = request.getParameterValues("token");
		token = tokens[tokens.length - 1] ;*/
		ConstantFinalUtil.loggerMsg.info("--token:{}--",token);
		
		/* 验证Token的合法性 */
		String requestURL = ConstantFinalUtil.BUNDLE.getString("users.center.head.validatorTokenUrl");
		HttpUtil httpUtil = new HttpUtil();
		
		/* 拼装JSON,验证token需要的JSON */
		/* {"version":"1","data":{"token":"40639117-f3fd-4151-bbdb-c47fb54623bf"}}
		 * */
		JSONObject requestJSON = new JSONObject() ; 
		requestJSON.put("version", "1");
		JSONObject dataJSON = new JSONObject();
		dataJSON.put("token", token);
		requestJSON.put("data", dataJSON);
		
		try
		{
			Map<String, String> paramsMap = new HashMap<String, String>();
			paramsMap.put("json", requestJSON + "");
			String responseStr = httpUtil.methodPost(requestURL, Collections.EMPTY_MAP, paramsMap);
			ConstantFinalUtil.loggerMsg.info("-验证-token返回:{}--",responseStr);
			JSONObject responseJSON = (JSONObject) JSON.parse(responseStr);
			/* 处理token */
			if("0".equalsIgnoreCase(responseJSON.getString("code")))
			{
				/* 成功 */
				JSONObject dataResJSON = responseJSON.getJSONObject("data");
				if(dataResJSON.get("users") != null)
				{
					/* token合法 */
					
					/* 将token对应的管理员信息放到session中 */
					JSONObject adminsJSON = (JSONObject) dataResJSON.get("users");
					adminsJSON.put("token", token);
					
					/* 从session中取数据,存储到数据库中 */
					/* 将JSON转换为管理员对象 */
					
					/* 如果是第一次登陆,就new一个对象,如果是第二次登陆,从数据库查询吧
					 * 二话不说,先查询数据库
					 *  */
					Map<String, Object> paramMap = new HashMap<String, Object>();
					/* 从用户中心返回的JSON中取id,也就是商城中管理员的ssoId */
					paramMap.put("ssoId", adminsJSON.get("id"));
					users = this.userService.queryOneAUsersService(paramMap);
					/* 一开始,先默认为更新, */
					boolean updateFlag = true ; 
					if(users == null)
					{
						users = new AUsers();
						users.setStatus(Byte.valueOf("1"));
						users.setCreateTime(new Date());
						/* 再改为false,要插入 */
						updateFlag = false ; 
					}
					users = users.parseObject(adminsJSON);
					
					/* 只有上次登陆时间有用 */
					users.setUpdateTime(new Date());
					if(updateFlag)
					{
						this.userService.insertOneAUsersService(users);
					}else
					{
						/* 存储数据库 */
						this.userService.updateOneAUsersService(users);
					}
					
					session.setAttribute("users", users);
					//将购物车的信息存储到数据库中
					this.insertShopCarBatch(request,response,users);
					return true ; 
				}
			}
		} catch (Exception e)
		{
			ConstantFinalUtil.loggerMsg.error("用户验证Token失败了,token:{}",token,e);
		}
		
		/*----------步骤:1------------*/
		/* 获取returnUrl:当前即将访问的url */
		String returnUrl = request.getRequestURL() + "";
		/* 获取?后面的内容 */
		String queryStr = request.getQueryString() ;
		if(queryStr == null)
		{
			queryStr = "" ; 
		}
		
		/* 拼装returnUrl */
		if(queryStr.length() > 0 )
		{
			returnUrl = returnUrl + "?" +  queryStr ;
		}
		ConstantFinalUtil.loggerMsg.info("--currUrl:{}--queryStr:{}",returnUrl,queryStr);
		
		/* 跳转到用户中心的登陆页面,并且将returnUrl带上去 */
		String usersCenterLoginUrl = ConstantFinalUtil.BUNDLE.getString("users.center.head.loginUrl") + "&returnUrl=" + URLEncoder.encode(returnUrl, "UTF-8") ;
		ConstantFinalUtil.loggerMsg.info("--usersCenterLoginUrl:{}",usersCenterLoginUrl);
		/* 客户端跳转 */
		response.sendRedirect(usersCenterLoginUrl);
		return false;
	}
	/**
	 * 将cookie中的购物车信息存储到数据
	 * @param request
	 * @param response
	 * @param user
	 * */
	public void insertShopCarBatch(HttpServletRequest request,HttpServletResponse response,AUsers users)
	{
		String shopCarListStr="[]";
		//从cookie中取数据
		Cookie[] cookies=request.getCookies();
		Cookie cookieTemp=null;
		if(cookies!=null)
		{
			for(int i=0;i<cookies.length;i++)
			{
				cookieTemp=cookies[i];
				if("shopCarList".equalsIgnoreCase(cookieTemp.getName()))
				{
					//赋值购物车的json数据
					shopCarListStr=cookieTemp.getValue();
					break;
				}
			}
		}
		//将cookie的数据转换成json对象
		JSONArray shopCarArr=JSON.parseArray(shopCarListStr);
		Map<String,Object> paramMap=new HashMap<String,Object>();
		for(Iterator it=shopCarArr.iterator();it.hasNext();)
		{
			JSONObject json=(JSONObject) it.next();
			String gid=json.getString("id");
			String num=json.getString("num");
			/* 需要存储到数据库中 */
			/*
			 * 用户未登陆,收藏了A,B,C三件商品
			 * 用户登陆,三件商品入库吧.
			 * 用户退出,购物车清空
			 * 用户又收藏了A,B两件商品,
			 * 用户又登陆(还是这个人).
			 * */
			paramMap.clear();
			paramMap.put("usersId",users.getId());
			paramMap.put("goodsId", gid);
			AUsersCar usersCar=this.userService.queryOneAUsersCarService(paramMap);
			
			//设置断言
			boolean flag=false;
			if(usersCar==null)
			{
				usersCar=new AUsersCar();
				usersCar.setGoodsId(Integer.valueOf(gid));
				usersCar.setUsersId(users.getId());
				usersCar.setNum(Integer.valueOf(num));
				usersCar.setStatus(Byte.valueOf("1"));
				usersCar.setCreateTime(new Date());
				flag = false ; 
			}else
			{
				//同一个用户,同一个商品,数据的购物车已经存在,应该拿老的数量+新的商品数量
				usersCar.setNum(usersCar.getNum()+Integer.valueOf(num));
			}
			usersCar.setUpdateTime(new Date());
			usersCar.setPubTime(new Date());
			
			//如果已经存在购物车,则更新;否则直接插入新的记录
			if(flag)
			{
				this.userService.updateOneAUsersCarService(usersCar);
			}else
			{
				this.userService.insertOneAUsersCarService(usersCar);
			}
			//执行完成之后,则要清楚cookie,防止再显示旧的购物车信息
			if(cookieTemp!=null)
			{
				cookieTemp.setPath(request.getContextPath());
				//空的json数组
				cookieTemp.setValue("[]");
				response.addCookie(cookieTemp);
			}
		}
	}
}